<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="chrome://global/skin"?>
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
                 type="text/css"?>
<window onload="runTests()"
        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<iframe height="200" width="600" type="content"></iframe>
<iframe height="200" width="600" type="content"></iframe>
<script type="application/javascript">
<![CDATA[
var is = window.opener.wrappedJSObject.is;
var isnot = window.opener.wrappedJSObject.isnot;
var ok = window.opener.wrappedJSObject.ok;
var todo = window.opener.wrappedJSObject.todo;
var SimpleTest = window.opener.wrappedJSObject.SimpleTest;
var gWbp;
var ctx1;
var ctx2;
var counter = 0;

var file = Components.classes["@mozilla.org/file/directory_service;1"]
             .getService(Components.interfaces.nsIProperties)
             .get("TmpD", Components.interfaces.nsILocalFile);
filePath = file.path;

function printpreview() {
  gWbp = window.frames[1].QueryInterface(Components.interfaces.nsIInterfaceRequestor)
             .getInterface(Components.interfaces.nsIWebBrowserPrint);
  var listener = {
    onLocationChange: function(webProgress, request, location, flags) { },
    onProgressChange: function(webProgress, request, curSelfProgress, 
                               maxSelfProgress, curTotalProgress,
                               maxTotalProgress) { },
    onSecurityChange: function(webProgress, request, state) { },
    onStateChange: function(webProgress, request, stateFlags, status) { },
    onStatusChange: function(webProgress, request, status, message) { },
    QueryInterface: function(iid) {
      if (iid.equals(Components.interfaces.nsIWebProgressListener) ||
          iid.equals(Components.interfaces.nsISupportsWeakReference))
            return this;
      throw Components.results.NS_NOINTERFACE;
    }
  }
  var prefs = Components.classes["@mozilla.org/preferences-service;1"]
                            .getService(Components.interfaces.nsIPrefBranch);
  prefs.setBoolPref('print.show_print_progress', false);
  //XXX I would have thought this would work, instead I'm forced to use prefs service
  gWbp.globalPrintSettings.showPrintProgress = false;
  var before = 0;
  var after = 0;
  function beforeprint() { ++before; }
  function afterprint() { ++after; }
  window.frames[0].addEventListener("beforeprint", beforeprint, true);
  window.frames[0].addEventListener("afterprint", afterprint, true);
  gWbp.printPreview(gWbp.globalPrintSettings, window.frames[0], listener);
  is(before, 1, "Should have called beforeprint listener!");
  is(after, 1, "Should have called afterprint listener!");
  window.frames[0].removeEventListener("beforeprint", beforeprint, true);
  window.frames[0].removeEventListener("afterprint", afterprint, true);
  prefs.clearUserPref('print.show_print_progress');
}

function exitprintpreview() {
  window.frames[1].QueryInterface(Components.interfaces.nsIInterfaceRequestor)
   .getInterface(Components.interfaces.nsIWebBrowserPrint).exitPrintPreview(); 
}

function finish() {
  SimpleTest.finish();
  window.close();
}

function runTests()
{
  var printService = Components.classes["@mozilla.org/gfx/printsettings-service;1"]
                               .getService(Components.interfaces.nsIPrintSettingsService);

  try {
    Components.classes["@mozilla.org/gfx/printerenumerator;1"]
              .getService(Components.interfaces.nsIPrinterEnumerator);
  } catch(e) {
    todo(false, "Test skipped on MacOSX, as the print preview code doesn't work there");
    finish();
    return;
  }

  if (printService.defaultPrinterName != '') {
    startTest1();
  } else {
    todo(false, "No printer seems installed on this machine, that is necessary for this test");
    finish();
  }
}

function compareCanvases() {
  return window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
               .getInterface(Components.interfaces.nsIDOMWindowUtils)
               .compareCanvases(document.getElementsByTagName("canvas")[0],
                                document.getElementsByTagName("canvas")[1],
                                {}) == 0;
}

function addHTMLContent(parent) {
  var n = parent.ownerDocument.createElement("div");
  parent.appendChild(n);
  var s = "<iframe width='500' height='40' src='data:text/plain,ThisIsAnIframeCreatedDuringPrintPreview'></iframe>";
  s += "<table>";
  for (var i = 1; i < 501; ++i) {
    s += "<tr><td>Cell A" + i + "</td><td>Cell B" + i + "</td><td>Cell C" + i + "</td></tr>";
  }
  s += "</table>";
  n.innerHTML = s;
}

function startTest1() {
  ctx1 = document.getElementsByTagName("canvas")[0].getContext("2d");
  ctx2 = document.getElementsByTagName("canvas")[1].getContext("2d");
  window.frames[0].document.body.innerHTML = "<div> </div><div>" + counter + " timers</div><div> </div>";

  // Note this timeout is needed so that we can check that timers run
  // after print preview, but not during it.
  window.frames[0].wrappedJSObject.counter = counter;
  window.frames[0].counterTimeout = "document.body.firstChild.nextSibling.innerHTML = ++counter + ' timers';" +
                                    "window.setTimeout(counterTimeout, 0);";
  window.frames[0].setTimeout(window.frames[0].counterTimeout, 0);
  window.frames[0].document.body.firstChild.innerHTML = "Print preview";

  printpreview();
  ctx1.drawWindow(window.frames[1], 0, 0, 400, 400, "rgb(256,256,256)");
  window.frames[0].document.body.firstChild.innerHTML = "Galley presentation";

  // Add some elements.
  addHTMLContent(window.frames[0].document.body.lastChild);
  // Delete them.
  window.frames[0].document.body.lastChild.innerHTML = "";
  // And readd.
  addHTMLContent(window.frames[0].document.body.lastChild);

  setTimeout(finalizeTest1, 1000);
}

function finalizeTest1() {
  ctx2.drawWindow(window.frames[1], 0, 0, 400, 400, "rgb(256,256,256)");
  exitprintpreview();
  ok(compareCanvases(), "Canvas should be the same!");
  counter = window.frames[0].counter;
  // This timeout is needed so that we can check that timers do run after
  // print preview.
  setTimeout(runTest2, 1000);
}

function runTest2() {
  isnot(window.frames[0].document.body.firstChild.nextSibling.textContent, "0 timers", "Timers should have run!");
  isnot(window.frames[0].counter, 0, "Timers should have run!");
  counter = window.frames[0].counter;
  window.frames[0].counterTimeout = "";
  setTimeout(runTest3, 0);
}

var elementIndex = 0;
var compareEmptyElement = true;
var emptyFormElements =
  ["<input type='text'>",
   "<input type='password'>",
   "<input type='file'>",
   "<input type='button'>",
   "<input type='submit'>",
   "<input type='reset'>",
   "<input type='checkbox'>",
   "<input type='radio'>",
   "<select></select>",
   "<select size='5'></select>",
   "<textarea></textarea>"];

var formElements =
  ["<input type='text' value='text'>",
   "<input type='password' value='password'>",
   "<input type='file' value='" + filePath + "'>",
   "<input type='button' value='button'>",
   "<input type='submit' value='submit button'>",
   "<input type='reset' value='reset button'>",
   "<input type='checkbox' checked>",
   "<input type='radio' checked>",
   "<select><option>option1</option></select>",
   "<select size='5'><option>1</option><option>2</option><option>3</option></select>",
   "<textarea value='textarea'>textarea</textarea>"];

function runTest3() {
  if (compareEmptyElement) {
    var currentIndex = elementIndex;
    ++elementIndex;
    if (elementIndex >= emptyFormElements.length) {
      elementIndex = 0;
      compareEmptyElement = false;
    }
    compareFormElementPrint(emptyFormElements[currentIndex], emptyFormElements[currentIndex], true);
    return;
  } else if (elementIndex < emptyFormElements.length) {
    var currentIndex = elementIndex;
    ++elementIndex;
    compareFormElementPrint(emptyFormElements[currentIndex], formElements[currentIndex], false);
    return;
  }

  setTimeout(runTest4, 0)
}

function compareFormElementPrint(el1, el2, equals) {
  window.frames[0].document.body.innerHTML = el1;
  window.frames[0].document.body.firstChild.value =
    window.frames[0].document.body.firstChild.getAttribute('value');
  printpreview();
  ctx1.drawWindow(window.frames[1], 0, 0, 400, 400, "rgb(256,256,256)");
  exitprintpreview();
  window.frames[0].document.body.innerHTML = el2;
  window.frames[0].document.body.firstChild.value =
    window.frames[0].document.body.firstChild.getAttribute('value');
  printpreview();
  ctx2.drawWindow(window.frames[1], 0, 0, 400, 400, "rgb(256,256,256)");
  exitprintpreview();
  is(compareCanvases(), equals,
     "Comparing print preview didn't succeed [" + el1 + " : " + el2 + "]");
  setTimeout(runTest3, 100);
}

// This is a crash test for bug 539060.
function runTest4() {
  window.frames[0].document.body.innerHTML =
    "<iframe style='display: none;' src='data:text/html,<iframe>'></iframe>";
  setTimeout(runTest4end, 500);
}

function runTest4end() {
  printpreview();
  exitprintpreview();

  runTest5();
}

// This is a crash test for bug 595337
function runTest5() {
  window.frames[0].document.body.innerHTML =
    '<iframe style="position: fixed; visibility: hidden; bottom: 10em;"></iframe>' +
    '<input contenteditable="true" style="display: table; page-break-before: left; width: 10000px;">';
  printpreview();
  exitprintpreview();

  setTimeout(runTest6, 0);
}

// Crash test for bug 878037
function runTest6() {
  window.frames[0].document.body.innerHTML =
    '<style> li { list-style-image: url("animated.gif"); } </style>' +
    '<li>Firefox will crash if you try and print this page</li>';

  setTimeout(runTest6end, 500);
}

function runTest6end() {
  printpreview();
  exitprintpreview();

  finish();
}

]]></script>
<table style="border: 1px solid black;" xmlns="http://www.w3.org/1999/xhtml">
<tr><th>Print preview canvas 1</th><th>Print preview canvas 2</th></tr>
<tr>
<td><canvas height="400" width="400"></canvas></td>
<td><canvas height="400" width="400"></canvas></td>
</tr></table>
</window>
